import java.util.Vector;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;
import java.util.jar.*;
import java.util.Enumeration;

public class AccessModeManager {
	private File directory;
	private Vector<AccessMode> accModes;
	
	public AccessModeManager(){
		accModes=new Vector<AccessMode>();
		directory=new File("/");
	}
	
	public void setDirectory(String dir) {directory= new File(dir);};
	public void loadPlugins() throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException	{
		File[] pliki=directory.listFiles();
		LinkedList<URL> urls= new LinkedList<URL>();
		LinkedList<String> classes= new LinkedList<String>();
		urls.add(directory.toURI().toURL());
	
		for(int i=0;i<pliki.length;i++)
		{
			//System.out.println(pliki[i].getName());
			if(pliki[i].getName().endsWith(".jar")) {
				JarFile jfile;
				String path="jar:" + pliki[i].toURI().toURL() + "!/";
				urls.add(new URL(path));

				try {
					jfile = new JarFile(pliki[i]);
					Enumeration<JarEntry> entries = jfile.entries();
					while (entries.hasMoreElements()) {
						JarEntry jentry=entries.nextElement();
						String cname=jentry.getName();
						//System.out.println("  in jar: "+cname);
						if(cname.endsWith(".class")) classes.add(cname.replace(".class",""));
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else
			if(pliki[i].getName().endsWith(".class")) {
				String cname=pliki[i].getName().replace(".class","");
				classes.add(cname);
			}
		}
			
		URL[] castUrls = new URL[urls.size()];
		urls.toArray(castUrls);
		URLClassLoader cl=URLClassLoader.newInstance(castUrls, ClassLoader.getSystemClassLoader());
		
		while(classes.size()>=0)	{
			String cname=classes.removeLast();
			try{
				Class<?> cls= cl.loadClass(cname);
				if(cls.getSuperclass().equals(AccessMode.class))
				{
					AccessMode tmp=(AccessMode)cls.newInstance();
					accModes.add(tmp);
				}
				/*for(int k=0;k<cls.getInterfaces().length;k++) {
					if(cls.getInterfaces()[k].equals(AccessMode.class)) {
						AccessMode tmp=(AccessMode)cls.newInstance();
						accModes.add(tmp);
						break;
					}
				}*/
			}catch(ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void unloadPlugins() { accModes.clear(); }
	public int getNumModes() { return accModes.size(); }
	public Vector<AccessMode> getModes(){ return accModes; }
}


